//
//  MyMeetingViewModel.swift
//  CleanArchitecture
//
//  Created by siri on 2024/11/6.
//  Copyright © 2024 Tuan Truong. All rights reserved.
//  业务逻辑层



import Combine
import UIKit
import Factory
import SwiftUI
class LoginViewModel: GetLogin,ShowMyMeeting{ // swiftlint:disable:this final_class
    unowned let navigationController: UINavigationController
    
    @Injected(\.loginGateway)
    var loginGateway: LoginGatewayProtocol
    
    init(navigationController:
         UINavigationController) {
        self.navigationController = navigationController
    }
    
    // 跳转
    func vm_showMyMeeting() {
        showMyMeeting()
    }
    

    // 页面加载时发送网络请求获取参数
//    func vmgetLogin() -> AnyPublisher< Res<TokenOutVO>, Error> {
//        return  getLogin(username: "01287", password: "QQpp0000!")
//    }

    
    // 销毁
    deinit {
        print("MyMeetingViewModel deinit")
    }
}

// MARK: - ViewModel
extension LoginViewModel: ObservableObject, ViewModel {
    
    // 处理事件
    struct Input {
        let loadTrigger: AnyPublisher<Void, Never>
        let reloadTrigger: AnyPublisher<Void, Never>
        let selectTrigger: AnyPublisher<Void, Never>
        let loginTrigger: AnyPublisher<Void, Never>
        let checkPattenTrigger: AnyPublisher<Void, Never>
    }
    
    
    // 页面相关数据
    final class Output: ObservableObject {
        @Published var username = "01287" // 账号
        @Published var password = "QQpp0000!" // 密码
        @Published var showForgotPasswordSheet = false // 是否显示忘记密码二维码
        @Published var showPattenFailure = false // 账号或密码是否为空
        @Published var showPattenFailureAll = false // 账号和密码是否都为空
        @Published var passCheckPattern = false // 是否通过格式检验
        @Published var failureText = "" // 失败信息
        @Published  var showLoginFailure = false // 登录失败
        @Published var isLoading = false // 页面加载
        @Published var isReloading = false // 刷新页面数据
        @Published var alert = AlertMessage() // 错误提示
    }
    
    // 监听事件并返回页面需要的数据
    func transform(_ input: Input, cancelBag: CancelBag) -> Output {
        
        // 页面初始化时加载的数据 配置并解构
//        let config = FetchItemConfig(initialLoadTrigger: input.loadTrigger,
//                                     reloadTrigger: input.reloadTrigger,
//                                     fetchItem:vmgetLogin)
//        
//        let (userinfo, error, isLoading, isReloading) = fetchItem(config: config).destructured
        
        let output = Output()
        
        // 页面初始化请求的网络数据
//        userinfo
//            .map { $0 }
//            .assign(to: \.result, on: output)
//            .store(in: cancelBag)
//        
//        error
//            .receive(on: RunLoop.main)
//            .map { AlertMessage(error: $0) }
//            .assign(to: \.alert, on: output)
//            .store(in: cancelBag)
//        
//        isLoading
//            .assign(to: \.isLoading, on: output)
//            .store(in: cancelBag)
//        
//        isReloading
//            .assign(to: \.isReloading, on: output)
//            .store(in: cancelBag)
        
        // 格式校验
        input.checkPattenTrigger.sink {
                   if (output.username == "" && output.password == "") {
                       // 显示失败信息
                       output.showPattenFailureAll = true
                       output.failureText = "账号和密码均不能为空"
                       DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                           withAnimation {
                               output.showPattenFailureAll  = false
                           }
                       }
                       return
                   }else if(output.username == "") {
                       // 显示失败信息
                       output.failureText = "账户不能为空"
                       output.showPattenFailure = true
                       // 弹窗显示后，设置一个定时器来关闭弹窗
                       DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                           withAnimation {
                               output.showPattenFailure = false
                           }
                       }
                       return
                   }else if(output.password == "") {
                       // 显示失败信息
                       output.failureText = "密码不能为空"
                       output.showPattenFailure = true
                       // 弹窗显示后，设置一个定时器来关闭弹窗
                       DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
                           withAnimation {
                               output.showPattenFailure = false
                           }
                       }
                       return
                   }
                   output.passCheckPattern = true
        } .store(in: cancelBag)
        
        // 发送登录请求事件
        input.loginTrigger.sink{
            // 请求登录
            let response =  self.getLogin(username: output.username , password: output.password)
             response.sink { completion in
                 switch completion {
                    case .finished:
                        // 请求成功完成，通常不需要额外处理
                        break
                    case .failure(let error):
                        // 失败的请求处理
                        print(error)
                  
                 }
             } receiveValue: { value in
                 if (value.data != nil) {
                     // 全局保存token
                     SettingsManager.shared.setToken(value.data?.tokenVO?.token ?? "" )
                     // 全局保存用户信息
                     SettingsManager.shared.setUserInfo(value.data?.tokenVO?.info ?? Token.Info())
                     self.showMyMeeting()
                 }else {
                     // 显示失败信息
                     output.failureText = "用户名或密码不正确，请重新输入。"
                     output.showLoginFailure = true
                 }
                
             }.store(in: cancelBag)
            // 重置是否通过格式检验条件
            output.passCheckPattern = false
        } .store(in: cancelBag)
        
        
        // 跳转事件
        input.selectTrigger
            .sink{
                    self.vm_showMyMeeting()
            }
            .store(in: cancelBag)
        
        return output
    }
}

